package com.markbuikema.juliana32.adapter;

import java.util.ArrayList;
import java.util.List;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnHoverListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.koushikdutta.urlimageviewhelper.UrlImageViewHelper;
import com.markbuikema.juliana32.MainActivity;
import com.markbuikema.juliana32.R;
import com.markbuikema.juliana32.asynctask.NieuwsRetriever;
import com.markbuikema.juliana32.fragment.NieuwsFragment;
import com.markbuikema.juliana32.model.nieuws.FacebookNieuwsItem;
import com.markbuikema.juliana32.model.nieuws.NieuwsItem;
import com.markbuikema.juliana32.model.nieuws.NieuwsItem.OnContentLoadedListener;
import com.markbuikema.juliana32.model.nieuws.WebsiteNieuwsItem;
import com.markbuikema.juliana32.util.Constants;
import com.markbuikema.juliana32.util.DataManager;
import com.markbuikema.juliana32.util.DateTimeUtils;
import com.markbuikema.juliana32.util.Util;
import com.markbuikema.juliana32.util.Util.LinkifyExtra;

public class NieuwsAdapter extends ArrayAdapter<NieuwsItem> {

	private List<NieuwsItem> items;
	private int columnCount;

	private static final int VIEW_TYPE_HEADER = 0;
	private static final int VIEW_TYPE_WEBSITE = 1;
	private static final int VIEW_TYPE_FACEBOOK_PHOTO = 2;
	private static final int VIEW_TYPE_FACEBOOK = 3;

	public NieuwsAdapter(Context context) {
		super(context, 0);
		columnCount = context.getResources().getInteger(R.integer.column_count);
		items = new ArrayList<NieuwsItem>(DataManager.getInstance().getNieuwsItems());

	}

	@Override
	public NieuwsItem getItem(int position) {
		return position < columnCount ? null : items.get(position - columnCount);
	}

	@Override
	public int getCount() {
		return items.size() + columnCount;
	}

	@Override
	public boolean isEnabled(int position) {
		return position >= columnCount;
	}

	@Override
	public int getViewTypeCount() {
		return 4;
	}

	@Override
	public void clear() {
		items.clear();
		notifyDataSetChanged();
	}

	/**
	 * DO NOT USE. DOES NOT WORK.
	 * 
	 * @deprecated use update() after adding all items to
	 *             DataManager.getInstance().getNieuwsItems();
	 */
	@Deprecated
	@Override
	public void add(NieuwsItem object) {
	}

	public void update() {
		items = new ArrayList<NieuwsItem>(DataManager.getInstance().getNieuwsItems());
		notifyDataSetChanged();
	}

	@Override
	public int getItemViewType(int position) {
		if (position < columnCount)
			return VIEW_TYPE_HEADER;
		NieuwsItem item = getItem(position);
		if (item instanceof WebsiteNieuwsItem)
			return VIEW_TYPE_WEBSITE;
		else
			return ((FacebookNieuwsItem) item).isPhoto() ? VIEW_TYPE_FACEBOOK_PHOTO : VIEW_TYPE_FACEBOOK;
	}

	@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// if top row, return space
		if (position < columnCount) {
			View view = new View(getContext());
			Resources res = getContext().getResources();

			final TypedArray styledAttributes = getContext().getTheme().obtainStyledAttributes(new int[] { android.R.attr.actionBarSize });
			int defaultMargin = (int) styledAttributes.getDimension(0, 0);
			styledAttributes.recycle();

			int statusBarHeight = getContext().getResources().getDimensionPixelSize(R.dimen.status_bar_offset);

			int gridSpacing = res.getDimensionPixelSize(R.dimen.card_margin);
			view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, defaultMargin - gridSpacing + statusBarHeight));
			return view;
		}

		// else construct the appropriate view
		final NieuwsItem item = getItem(position);

		switch (getItemViewType(position)) {
		case VIEW_TYPE_WEBSITE:
			convertView = constructWebsiteView(getContext(), item, convertView);

			item.startLoading(new OnContentLoadedListener() {

				@Override
				public void onContentLoaded(String content, List<String> photos) {
				}
			});

			break;
		case VIEW_TYPE_FACEBOOK_PHOTO:
			FacebookNieuwsItem fbPhotoItem = (FacebookNieuwsItem) item;

			convertView = constructFacebookPhotoView(getContext(), fbPhotoItem, convertView);

			break;
		case VIEW_TYPE_FACEBOOK:
			FacebookNieuwsItem fbItem = (FacebookNieuwsItem) item;

			convertView = constructFacebookView(getContext(), fbItem, convertView);

			break;
		default:
			break;
		}

		final View view = convertView;

		final View touchFeedback = view.findViewById(R.id.nieuwsitem_touch_feedback);
		touchFeedback.setAlpha(0);
		touchFeedback.setVisibility(View.VISIBLE);

		view.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View arg0, MotionEvent arg1) {
				switch (arg1.getAction()) {
				case MotionEvent.ACTION_DOWN:
					touchFeedback.animate().alpha(1).setDuration(100).start();
					break;
				case MotionEvent.ACTION_UP:
					openNieuwsDetail(item, view);
				case MotionEvent.ACTION_OUTSIDE:
				case MotionEvent.ACTION_CANCEL:
					touchFeedback.animate().alpha(0).setDuration(300).start();
					break;
				}

				return true;
			}
		});

		final View hoverFeedback = view.findViewById(R.id.nieuwsitem_hover_feedback);
		hoverFeedback.setAlpha(0);
		hoverFeedback.setVisibility(View.VISIBLE);

		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
			view.setOnHoverListener(new OnHoverListener() {

				@Override
				public boolean onHover(View arg0, MotionEvent arg1) {
					switch (arg1.getAction()) {
					case MotionEvent.ACTION_HOVER_ENTER:
						// TODO hover effect
						break;
					case MotionEvent.ACTION_HOVER_EXIT:
						// TODO remove hover effect
						break;
					}
					return true;
				}
			});
		return convertView;

	}

	private void openNieuwsDetail(NieuwsItem item, View view) {
		MainActivity activity = (MainActivity) getContext();
		NieuwsFragment fragment = (NieuwsFragment) activity.getSupportFragmentManager().findFragmentByTag(NieuwsFragment.class.getName());

		fragment.openNieuwsDetail(item, view);
	}

	@Override
	public long getItemId(int position) {
		return position < columnCount ? 0 : position - columnCount;
	}

	public void setSearchword(String s) {
		clear();
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
		boolean facebook = prefs.getBoolean(Constants.KEY_FACEBOOK, true);
		boolean website = prefs.getBoolean(Constants.KEY_WEBSITE, true);

		new NieuwsRetriever(facebook, website) {
			public void onPostExecute(List<NieuwsItem> result) {
				items = result;
				notifyDataSetChanged();
			}
		}.execute(s);
	}

	public void clearSearchword() {
		clear();
		items = new ArrayList<NieuwsItem>(DataManager.getInstance().getNieuwsItems());
		notifyDataSetChanged();
	}

	@Override
	public void notifyDataSetChanged() {
		super.notifyDataSetChanged();
	}

	public static View constructWebsiteView(Context context, NieuwsItem item, View convertView) {

		WebsiteViewHolder holder;

		if (convertView == null) {
			convertView = LayoutInflater.from(context).inflate(R.layout.list_nieuws_website, null);
			holder = new WebsiteViewHolder();
			holder.title = (TextView) convertView.findViewById(R.id.nieuwsitem_title);
			holder.subTitle = (TextView) convertView.findViewById(R.id.nieuwsitem_subtitle);
			holder.createdAt = (TextView) convertView.findViewById(R.id.nieuwsitem_date);
			holder.title.setTypeface(Util.getRobotoCondensed(context));
			holder.subTitle.setTypeface(Util.getRobotoLight(context));
			holder.createdAt.setTypeface(Util.getRobotoCondensed(context));
			convertView.setTag(holder);
		} else {
			holder = (WebsiteViewHolder) convertView.getTag();
		}

		holder.title.setText(item.getTitle());
		holder.subTitle.setText(Util.trimTrailingWhitespace(LinkifyExtra.addLinksHtmlAware(item.getSubTitle())));
		holder.createdAt.setText(DateTimeUtils.getDateString(context, ((WebsiteNieuwsItem) item).getCreatedAt()));


		return convertView;
	}

	public static View constructFacebookView(Context context, FacebookNieuwsItem fbItem, View convertView) {
		FacebookViewHolder holder;

		if (convertView == null) {
			convertView = LayoutInflater.from(context).inflate(R.layout.list_nieuws_facebook, null);
			holder = new FacebookViewHolder();

			holder.title = (TextView) convertView.findViewById(R.id.facebook_content);
			holder.content = (TextView) convertView.findViewById(R.id.nieuwsitem_subtitle);
			holder.likeCount = (TextView) convertView.findViewById(R.id.facebook_likecount);
			holder.commentCount = (TextView) convertView.findViewById(R.id.facebook_commentcount);
			holder.createdAt = (TextView) convertView.findViewById(R.id.facebook_date);
			holder.title.setTypeface(Util.getRobotoCondensed(context));
			holder.createdAt.setTypeface(Util.getRobotoCondensed(context));
			holder.content.setTypeface(Util.getRobotoLight(context));
			holder.likeCount.setTypeface(Util.getRobotoLight(context));
			holder.commentCount.setTypeface(Util.getRobotoLight(context));
			convertView.setTag(holder);
		} else {
			holder = (FacebookViewHolder) convertView.getTag();
		}

		holder.title.setText(fbItem.getTitle());
		holder.content.setText(fbItem.getContent());
		holder.likeCount.setText(Integer.toString(fbItem.getLikeCount()));
		holder.commentCount.setText(Integer.toString(fbItem.getComments().size()));
		holder.createdAt.setText(DateTimeUtils.getDateString(context, fbItem.getCreatedAt()));

		return convertView;
	}

	public static View constructFacebookPhotoView(Context context, FacebookNieuwsItem fbPhotoItem, View convertView) {

		FacebookPhotoViewHolder holder;

		if (convertView == null) {
			convertView = LayoutInflater.from(context).inflate(R.layout.list_nieuws_facebook_photo, null);
			holder = new FacebookPhotoViewHolder();
			holder.pager = (ViewPager) convertView.findViewById(R.id.facebookPhotoPager);
			holder.singlePhotoView = (ImageView) convertView.findViewById(R.id.facebookSinglePhoto);
			holder.content = (TextView) convertView.findViewById(R.id.facebook_content);
			holder.likeCount = (TextView) convertView.findViewById(R.id.facebook_likecount);
			holder.commentCount = (TextView) convertView.findViewById(R.id.facebook_commentcount);
			holder.createdAt = (TextView) convertView.findViewById(R.id.facebook_date);
			holder.subTitle = (TextView) convertView.findViewById(R.id.nieuwsitem_subtitle);

			holder.createdAt.setTypeface(Util.getRobotoCondensed(context));
			holder.content.setTypeface(Util.getRobotoCondensed(context));
			holder.likeCount.setTypeface(Util.getRobotoLight(context));
			holder.commentCount.setTypeface(Util.getRobotoLight(context));
			holder.subTitle.setTypeface(Util.getRobotoLight(context));
			convertView.setTag(holder);
		} else {
			holder = (FacebookPhotoViewHolder) convertView.getTag();
		}

		boolean singlePhoto = fbPhotoItem.getAlbumId() == null && fbPhotoItem.getDefaultPhoto() != null;

		holder.singlePhotoView.setVisibility(singlePhoto ? View.VISIBLE : View.GONE);
		holder.pager.setVisibility(singlePhoto ? View.GONE : View.VISIBLE);

		if (!singlePhoto) {
			final PhotoPagerAdapter adapter = new PhotoPagerAdapter(context, fbPhotoItem, convertView);
			holder.pager.setCurrentItem(0, true);
			holder.pager.setOffscreenPageLimit(2);
			holder.pager.setAdapter(adapter);

			if (fbPhotoItem.getPhotoCount() == 0)
				fbPhotoItem.startLoading(new OnContentLoadedListener() {

					@Override
					public void onContentLoaded(String content, List<String> photos) {
						adapter.notifyDataSetChanged();
					}
				});
		} else
			UrlImageViewHelper.setUrlDrawable(holder.singlePhotoView, Util.PHOTO_URL_PREFIX + fbPhotoItem.getDefaultPhoto() + Util.PHOTO_URL_SUFFIX, R.drawable.silhouette);

		holder.content.setText(fbPhotoItem.getTitle());
		holder.subTitle.setText(fbPhotoItem.getContent());
		holder.likeCount.setText(Integer.toString(fbPhotoItem.getLikeCount()));
		holder.commentCount.setText(Integer.toString(fbPhotoItem.getComments().size()));
		holder.createdAt.setText(DateTimeUtils.getDateString(context, fbPhotoItem.getCreatedAt()));

		return convertView;
	}

	private static abstract class ViewHolder {
		TextView title;
		TextView subTitle;
		TextView createdAt;
	}

	private static class WebsiteViewHolder extends ViewHolder {

	}

	private static class FacebookViewHolder extends ViewHolder {
		TextView likeCount;
		TextView commentCount;
		TextView content;
	}

	private static class FacebookPhotoViewHolder extends ViewHolder {
		TextView likeCount;
		TextView commentCount;
		TextView content;
		ViewPager pager;
		ImageView singlePhotoView;
	}
}